package com.gcosc.hly.codejava.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gcosc.hly.codejava.Final.AnswerItemFinal;
import com.gcosc.hly.codejava.Utils.DozerUtils;
import com.gcosc.hly.codejava.Utils.RequestContextUtils;
import com.gcosc.hly.codejava.VO.AnswerItemDetailVO;
import com.gcosc.hly.codejava.VO.AnswerItemVO;
import com.gcosc.hly.codejava.VO.PageResult;
import com.gcosc.hly.codejava.entity.Answer;
import com.gcosc.hly.codejava.entity.AnswerItem;
import com.gcosc.hly.codejava.entity.Topic;
import com.gcosc.hly.codejava.entity.TopicResult;
import com.gcosc.hly.codejava.mapper.AnswerItemMapper;
import com.gcosc.hly.codejava.params.QueryParams;
import com.gcosc.hly.codejava.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class AnswerItemServiceImpl extends ServiceImpl<AnswerItemMapper, AnswerItem> implements AnswerItemService {

    private final TopicService topicService;
    private final TopicTestService topicTestService;
    private final TopicResultService topicResultService;
    private final DozerUtils dozerUtils;
    private final UserService userService;

    @Override
    public PageResult<AnswerItemVO> queryParams(QueryParams params) {

        int id = 0;

        int isUser = params.getIsUser();
        int status = params.getStatus();

        if (isUser == 0){
            id = RequestContextUtils.getUser().getId();
        }

        Page<AnswerItem> page = lambdaQuery()
                .eq(status != 0, AnswerItem::getResult, status)
                .eq(isUser == 0, AnswerItem::getUid, id)
                .eq(StringUtils.isNotBlank(params.getIds()), AnswerItem::getId, params.getIds())
                .eq(params.getUid() != 0,AnswerItem::getUid ,params.getUid())
                .eq(StringUtils.isNotBlank(params.getType()), AnswerItem::getType, params.getType())
                .eq(params.getAnswerId() != 0, AnswerItem::getAnswerId, params.getAnswerId())
                .eq(params.getIsNotAnswer() == 0, AnswerItem::getAnswerId, 0)
                .orderByDesc(AnswerItem::getCreateTime)
                .select(AnswerItem::getAnswerId,
                        AnswerItem::getId,
                        AnswerItem::getTopicId,
                        AnswerItem::getType,
                        AnswerItem::getResult,
                        AnswerItem::getCreateTime,
                        AnswerItem::getUid)
                .page(new Page<AnswerItem>(params.getPage(), params.getLimit()));


        List<AnswerItemVO> list = dozerUtils.convert(page.getRecords(), AnswerItemVO.class);

        list.forEach(n -> {
            Topic one = topicService.lambdaQuery().select(
                    Topic::getLevel,
                    Topic::getTitle
            ).eq(Topic::getId, n.getTopicId()).one();
            n.setTitle(one.getTitle());
            n.setLevel(one.getLevel());
            n.setUser(userService.getUserInfoVO(n.getUid()));
        });

        userService.clear();

        return PageResult.<AnswerItemVO>builder().page(page).list(list).build();
    }

    @Override
    public boolean codeTest(AnswerItem answerItem) {
        List<TopicResult> list = topicResultService.lambdaQuery()
                .eq(TopicResult::getTopicId, answerItem.getTopicId()).list();
        return topicTestService.test(list, answerItem);
    }

    @Override
    public void saveAnswerItem(AnswerItem answerItem) {
        if (AnswerItemFinal.JAVA.equals(answerItem.getType())){
            try {
                codeTest(answerItem);
                answerItem.setResult(1);
            }catch (Exception e){}
        }
        answerItem.setUid(RequestContextUtils.getUser().getId());
        save(answerItem);
    }

    @Override
    public int countFraction(int id) {
        int i = baseMapper.countFraction(id);
        int max = baseMapper.countMaxFraction(id);
        double v = Math.ceil((i + 0.0) / max * 100);
        return (int) v;
    }

    @Override
    public List<AnswerItemDetailVO> getDetailList(int aid) {
        return lambdaQuery().eq(AnswerItem::getAnswerId, aid).list()
                .stream().map(n -> getDetail(n)).collect(Collectors.toList());
    }

    @Override
    public AnswerItemDetailVO getDetail(AnswerItem answerItem) {
        return AnswerItemDetailVO.builder()
                .answerItem(answerItem)
                .topic(topicService.getById(answerItem.getTopicId()))
                .build();
    }

    @Override
    public List<AnswerItemDetailVO> getDetailByTopicIdsList(ArrayList<Integer> ids) {
        if (ids.size() == 0){
            return new ArrayList();
        }
        return topicService.listByIds(ids).stream().map(n ->
                AnswerItemDetailVO.builder().topic(n).build())
                .collect(Collectors.toList());
    }

}
